package com.geek.water.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geek.water.entity.Area;
import com.geek.water.exception.WaterException;
import com.geek.water.mapper.AreaMapper;
import com.geek.water.service.AreaService;
import com.geek.water.vo.AreaTreeVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yangwenqi
 * @decs TODO
 * @date 2025/7/28
 */
@Service
public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements AreaService {

    @Override
    public void validateAreaBeforeDelete(Long areaId) {
        // 检查是否有子区域
        if (hasChildren(areaId)) {
            throw new WaterException("区域存在子区域，无法删除");
        }
    }

    @Override
    public boolean hasChildren(Long areaId) {
        return lambdaQuery()
                .eq(Area::getParentAreaId, areaId)
                .count() > 0;
    }


    @Override
    public List<AreaTreeVO> buildAreaTree(List<Area> areas) {
        Map<Long, AreaTreeVO> nodeMap = new HashMap<>();
        List<AreaTreeVO> roots = new ArrayList<>();

        for (Area area : areas) {
            AreaTreeVO node = new AreaTreeVO();
            node.setId(area.getId());
            node.setName(area.getName());
            node.setParentAreaId(area.getParentAreaId());
            node.setChildren(new ArrayList<>());
            nodeMap.put(area.getId(), node);

            if (area.getParentAreaId() == null || area.getParentAreaId() == 0L) {
                roots.add(node);
            }
        }

        for (Area area : areas) {
            if (area.getParentAreaId() != null && area.getParentAreaId() != 0L) {
                AreaTreeVO parent = nodeMap.get(area.getParentAreaId());
                if (parent != null) {
                    parent.getChildren().add(nodeMap.get(area.getId()));
                }
            }
        }

        return roots;
    }

    @Override
    public void validateArea(Area area) {
        // 名称唯一性校验（同一站点、同一父区域下）
        boolean exists = lambdaQuery()
                .eq(Area::getSiteId, area.getSiteId())
                .eq(Area::getParentAreaId, area.getParentAreaId())
                .eq(Area::getName, area.getName())
                .ne(area.getId() != null, Area::getId, area.getId())
                .exists();
        if (exists) {
            throw new WaterException("同级区域名称不能重复");
        }

        // 父区域有效性校验
        if (area.getParentAreaId() != null && area.getParentAreaId() != 0L) {
            Area parent = getById(area.getParentAreaId());
            if (parent == null || !parent.getSiteId().equals(area.getSiteId())) {
                throw new WaterException("父区域不存在或不属于同一站点");
            }
        }
    }

    @Override
    @Transactional
    public void deleteBySiteId(Long siteId) {
        // 递归删除所有区域
        List<Area> areas = lambdaQuery().eq(Area::getSiteId, siteId).list();
        for (Area area : areas) {
            deleteAreaRecursive(area.getId());
        }
    }

    @Transactional
    public void deleteAreaRecursive(Long areaId) {
        // 先删除子区域
        List<Area> children = lambdaQuery().eq(Area::getParentAreaId, areaId).list();
        for (Area child : children) {
            deleteAreaRecursive(child.getId());
        }
        // 删除当前区域
        removeById(areaId);
    }

}
